package com.anjiplus.aj_flutter_tool;

import androidx.annotation.NonNull;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import java.util.List;
import java.util.Map;
import android.provider.Settings;
import java.util.concurrent.ConcurrentLinkedQueue;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry.Registrar;

/** AjFlutterToolPlugin */
public class AjFlutterToolPlugin implements FlutterPlugin, MethodCallHandler {
  private static Context mContext;
  /// The MethodChannel that will the communication between Flutter and native Android
  ///
  /// This local reference serves to register the plugin with the Flutter Engine and unregister it
  /// when the Flutter Engine is detached from the Activity
  private MethodChannel channel;
  private ConcurrentLinkedQueue<MethodResultWrapper> wrappers = new ConcurrentLinkedQueue<>();

  /**
   * Plugin registration.
   */
  @SuppressWarnings("deprecation")
  public static void registerWith(Registrar registrar) {
    mContext = registrar.activity();
    final MethodChannel channel = new MethodChannel(registrar.messenger(), "aj_flutter_tool");
    channel.setMethodCallHandler(new AjFlutterToolPlugin());
  }

  @Override
  public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
    mContext = flutterPluginBinding.getApplicationContext();
    channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "aj_flutter_tool");
    channel.setMethodCallHandler(this);
  }

  @Override
  public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
    removeAllWrapper();
    addWraper(new MethodResultWrapper(result));
    if (call.method.equals("getMetaInfo")) {
      String metaKey = "";
      Object parameter = call.arguments();
      if (parameter instanceof Map) {
        metaKey = (String) ((Map) parameter).get("metaKey");
      }
      getMetaInfo(metaKey);
    } else {
      MethodResultWrapper wrapper = peekWraper();
      if (wrapper != null) {
        wrapper.notImplemented();
      }
    }
  }

  @Override
  public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
    channel.setMethodCallHandler(null);
  }

  //从build.gradle读取配置
  private void getMetaInfo(String key) {
    String metaValue = null;
    try {
      ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfo(mContext.getPackageName(),
              PackageManager.GET_META_DATA);
      metaValue = getMetaInfoByKey(appInfo, key);
    } catch (Exception e) {

    }
    MethodResultWrapper wrapper = peekWraper();
    if (wrapper != null) {
      if (metaValue!=null) {
        wrapper.success(metaValue);
      } else {
        wrapper.success("failMeta");
      }
    }
  }

  /**
   * @param appInfo
   * @param key     在manifest文件配置meta的key
   * @return
   */
  private String getMetaInfoByKey(ApplicationInfo appInfo, String key) {
    Object value = appInfo.metaData.get(key);
    String valueStr = "";
    if (value != null) {
      valueStr = value.toString().trim();
    }
    return valueStr;
  }

  /**
   * 获取当前的result
   *
   * @return
   */
  private MethodResultWrapper peekWraper() {
    if (wrappers == null
            || wrappers.isEmpty()) {
      return null;
    }
    return wrappers.remove();
  }

  /**
   * 只考虑最后一次
   */
  private void removeAllWrapper() {
    if (wrappers == null) {
      return;
    }
    wrappers.clear();
  }

  /**
   * 加入唯一的result
   *
   * @param wrapper
   */
  private void addWraper(MethodResultWrapper wrapper) {
    if (wrappers == null) {
      return;
    }
    wrappers.add(wrapper);
  }

  // MethodChannel.Result wrapper that responds on the platform thread.
  private static class MethodResultWrapper implements MethodChannel.Result {
    private MethodChannel.Result methodResult;
    private Handler handler;

    MethodResultWrapper(MethodChannel.Result result) {
      methodResult = result;
      handler = new Handler(Looper.getMainLooper());
    }

    @Override
    public void success(final Object result) {
      handler.post(
              new Runnable() {
                @Override
                public void run() {
                  methodResult.success(result);
                }
              });
    }

    @Override
    public void error(
            final String errorCode, final String errorMessage, final Object errorDetails) {
      handler.post(
              new Runnable() {
                @Override
                public void run() {
                  methodResult.error(errorCode, errorMessage, errorDetails);
                }
              });
    }

    @Override
    public void notImplemented() {
      handler.post(
              new Runnable() {
                @Override
                public void run() {
                  methodResult.notImplemented();
                }
              });
    }
  }

}
